package com.loveazure.bll.algorithm;

import java.util.TreeSet;

import com.loveazure.bll.WordProvider;

public class SM2 implements Algorithm {

	/* 本次学习的单词set */
	private TreeSet<WordItem> sessionSet = new TreeSet<WordItem>(
			new WordItemComparator());

	/* 当前单词索引 */
	private int currentItemIndex;

	/* 单词提供者 */
	private WordProvider provider;

	public SM2(WordProvider provider) {
		this.provider = provider;

		WordItem[] items = provider.getAllLearnedWords();
		if (items != null && items.length > 0) {
			// compute interval for all learned words
			for (WordItem item : items) {
				int interval = computeInterval(item.getTimes(), item.getEF());
				item.setIndex(interval);
				sessionSet.add(item);
			}
		}
	}

	/**
	 * 从sessionList中获取一个单词，给UI显示
	 */
	@Override
	public WordItem displayWord() {
		if (sessionSet.size() == 0) {
			WordItem newWord = provider.getNewWord();
			if (newWord == null) {
				return null;
			}
			newWord.setIndex(currentItemIndex);
			sessionSet.add(newWord);
		}

		while (sessionSet.first().getIndex() > currentItemIndex) {
			WordItem newWord = provider.getNewWord();
			if (newWord == null) {
				currentItemIndex = sessionSet.first().getIndex();
			}
			newWord.setIndex(currentItemIndex);
			sessionSet.add(newWord);
			
		}

		return sessionSet.first();
	}

	@Override
	public void computeResult() {
		WordItem currentItem = sessionSet.pollFirst();

		double EF = currentItem.getEF();
		int quality = currentItem.getQuality();
		int interval;
		int times;

		if (quality < 3) {
			/*
			 * If the quality response was lower than 3 then start repetitions
			 * for the item from the beginning without changing the E-Factor
			 * (i.e. use intervals I(1), I(2) etc. as if the item was memorized
			 * anew).
			 */
			currentItem.setTimes(1);
		} else {
			/*
			 * After each repetition modify the E-Factor of the recently
			 * repeated item according to the formula:
			 */
			EF = EF + (0.1 - (5 - quality) * (0.08 + (5 - quality) * 0.02));

			/*
			 * If EF is less than 1.3 then let EF be 1.3.
			 */
			if (EF <= 1.3) {
				EF = 1.3;
			}
			currentItem.setEF(EF);
		}

		times = currentItem.getTimes();
		interval = computeInterval(times, EF);

		currentItemIndex++;

		currentItem.setIndex(currentItemIndex + interval);
		System.out.println(currentItem.getIndex());
		sessionSet.add(currentItem);
		System.out.println("index:" + currentItem.getIndex() + ",name:"
				+ currentItem.getName() + ",time:" + currentItem.getTimes()
				+ ",interval:" + interval);
	}

	/**
	 *Repeat items using the following intervals: <br />
	 * I(1):=1 <br/>
	 * I(2):=6 <br/>
	 * for n>2: I(n):=I(n-1)*EF
	 */
	private int computeInterval(int times, double EF) {
		int retInt = 0;
		if (times == 1) {
			retInt = 1;
		} else if (times == 2) {
			retInt = 6;
		} else {
			retInt = (int) (computeInterval(times - 1, EF) * EF);
		}
		return retInt;
	}
}
